#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<string.h>
#include<sys/wait.h>

#define NUM 1024
#define SIZE 32
#define SEP " "

char *g_argv[SIZE];// 保存打散后的命令行字符串
char cmd_line[NUM];// 做缓冲区, 保存完整的命令行字符串


int main()
{
  // 0、常驻内存的进程，不退出
  while(1)
  {
    // 1、打印提示信息
    // [zzy@VM-4-4-centos shell]@
    printf("[test@VM-4-4-centos shell]@ ");
    fflush(stdout);
    memset(cmd_line, '\0', sizeof(cmd_line));
    // 2、获取用户键盘上输入的指令
    if(fgets(cmd_line, sizeof(cmd_line), stdin) == NULL)// 出错了
    {
      continue;
    }

    cmd_line[strlen(cmd_line) - 1] = '\0';
    printf("echo: %s\n", cmd_line);
    // 3、命令行解析 ”ls -a -l“--->"ls" "-a" "-l"
    g_argv[0] = strtok(cmd_line, SEP);// 第一次调用传入原始字符串
    int index = 1;
    while(g_argv[index++] = strtok(NULL, SEP));// 第二次还要解析原字符串，传NULL
    {
      // g_argv[index] = strtok(NULL, SEP);// 第二次还要解析原字符串，传NULL
    }

    // for(index = 0; g_argv[index]; index++)
    // {
    //  printf("%s");
    // }
    
    // 4、内置命令，让父进程自己执行的命令
    // 内置命令本质是shell下的一个函数调用
    if(strcmp(g_argv[0], "cd") == 0)// 不想让子进程执行
    {
      if(g_argv[1] != NULL)
        chdir(g_argv[1]);//更改目录  cd path  cd .. 等等
      continue;
    }
    // 5、fork
    pid_t id = fork();
    if(!id)
    {
      // child
      printf("子进程进行的：");
      fflush(stdout);
      execvp(g_argv[0], g_argv);
      exit(1);
    }
    // 父进程
    int status = 0;
    pid_t ret = waitpid(id, &status, 0);
    if(ret > 0)
      printf("exit code: %d\n",WEXITSTATUS(status));


  }
  return 0;
}
